﻿import flash.display.FrameLabel;
import flash.display.Graphics;
import mx.rpc.http.HTTPService;
import mx.rpc.events.ResultEvent;
import mx.managers.PopUpManager;
import mx.collections. *;
import mx.controls. *;
import com.esri.ags.Map;
import com.esri.ags.geometry.Extent;
import mx.collections.ArrayCollection;
import com.adobe.serialization.json.JSON;
import com.uprr.app.tnm.events.AppEvent;
import com.uprr.app.tnm.events.EventBus;

import mx.collections.SortField;
import mx.collections.Sort;
import mx.events.*;

import com.esri.ags.geometry.MapPoint;     
import com.esri.ags.geometry.Extent;   
import com.esri.ags.geometry.Geometry;            
import com.esri.ags.Graphic;            
import com.esri.ags.symbol.SimpleMarkerSymbol;
import com.esri.ags.symbol.InfoSymbol;
import com.esri.ags.symbol.InfoSymbol;

import com.uprr.app.tnm.model.Model;
import com.esri.ags.utils.*;
import mx.managers.CursorManager;

import com.esri.ags.geometry.Polyline;
import flash.net.*;

// MP locator
[Bindable]
private var sbdvArray:ArrayCollection = new ArrayCollection();

[Bindable]
private var mpArray:ArrayCollection = new ArrayCollection();

private var delayTimer:Timer; 
	
	/**
	 * initialization
	 */		
	private function init():void {
		EventBus.addEventListener (AppEvent.MP_DOUBLECLICK, mapToMilepost);
		sbdvSel.enabled = false;
		CursorManager.setBusyCursor ();
		loadSubList();		
	}
	
	
 /**
	 *  Load distinctive train symbol for autoComplete at stratup
	 */
	private function loadSubList():void {
	// disable caching
	var rnd : Number = Math.round(Math.random()*1000);
	var httpRequest:HTTPService =new HTTPService();
		httpRequest.url="GetSubList?x="+rnd;
		
	var parameters:Object=new Object();
	parameters.action="load";
	httpRequest.request=parameters;
	httpRequest.resultFormat="text";
	httpRequest.addEventListener(ResultEvent.RESULT, subListResulteHandler);
	httpRequest.addEventListener("fault", serviceFaultHandler);
	httpRequest.send();
}

/**
 * @param	event
 */
 private function subListResulteHandler (event : ResultEvent) : void
{
	var rawData : String = String (event.result);
	try 
	{
		var arr : Array = (JSON.decode (rawData) as Array);
		for (var i : int = 0; i < arr.length; i ++)
		{
		sbdvArray.addItem ({"name":arr[i].sbdvName, "code":arr[i].sbdvCode, "startMile":arr[i].startMile, "endMile":arr[i].endMile}); 
		}
		
		CursorManager.removeBusyCursor ();
		sbdvSel.enabled = true;
		
	} catch (err : Error)
	{
		var errorEvent : AppEvent = new AppEvent (AppEvent.APP_ERROR);
		errorEvent.data = "Error when loading subdivision list: "+err.toString();
		errorEvent.dispatch ();
	}
		
}

/**
 * @param	event
 */
private function serviceFaultHandler (event : Event) : void
{
	var errorEvent : AppEvent = new AppEvent (AppEvent.APP_ERROR);
		errorEvent.data = "Error when loading data";
		errorEvent.dispatch ();
}

/**
 *  Add handler
 */
private function getMilepostLoc():void {
	    CursorManager.setBusyCursor ();		
		var mile:String = mile.text; 
		var sbdvCode:String = sbdvSel.selectedItem.code as String;
		var sbdvName:String = sbdvSel.selectedItem.name as String;
		
		/**
		 *  todo - validate mile value
		 */
		var mVal:Number = new Number(mile);
		if (mVal < sbdvSel.selectedItem.startMile || mVal > sbdvSel.selectedItem.endMile ) {
		
			var warnEvent : AppEvent = new AppEvent (AppEvent.APP_WARN);
			warnEvent.data = "Mile value is off " + sbdvName + " limits ("
			+sbdvSel.selectedItem.startMile+" ~ "+sbdvSel.selectedItem.endMile+")";
			warnEvent.dispatch ();
			CursorManager.removeBusyCursor ();	
			return;
		} 
			
		
		var rnd : Number = Math.round(Math.random()*1000);
		var httpRequest:HTTPService =new HTTPService();
		httpRequest.url="GetPosInSbdvByMile?x="+rnd;
		
		var parameters:Object=new Object();
		parameters.sbdvName = sbdvName;
		parameters.sbdvCode=sbdvCode;
		parameters.mile = mile;
	
		httpRequest.request=parameters;
		httpRequest.resultFormat="text";
		httpRequest.addEventListener(ResultEvent.RESULT, getMilepostLocResulteHandler);
		httpRequest.addEventListener("fault", serviceFaultHandler);
		httpRequest.send();
		//Alert.show("Train:"+symb+day);
}

/**
 * @param	event
 */
 private function getMilepostLocResulteHandler (event : ResultEvent) : void
{
	var rawData : String = String (event.result);
	try 
	{
		var mp:Object=(JSON.decode (rawData) as Object);
		mpArray.addItem ({"sbdvName":mp.sbdvName,"sbdvCode":mp.sbdvCode, "mile":mp.mile, "lat":mp.lat, "lon":mp.lon}); 
		drawMilepost(mp);
		
		 CursorManager.removeBusyCursor ();	
		
	} catch (err : Error)
	{
		var errorEvent : AppEvent = new AppEvent (AppEvent.APP_ERROR);
		errorEvent.data = "Error when adding milepost: "+err.toString();
		errorEvent.dispatch ();
	}
}


// auto_complete
private function handleSearchChange():void 
			{
				if (delayTimer != null && delayTimer.running) 
				{
					delayTimer.stop();
				}
				
				if (sbdvSel.searchText.length > 2 && sbdvArray.length == 0) 
				{
					// if you remove below line then it kind of works
					// but it is more correct to remove all data
					// before repopulate. Really it is just holding
					// on to stale data
					sbdvArray.removeAll();
					delayTimer = new Timer( 500, 1 );
					delayTimer.addEventListener(TimerEvent.TIMER, showComboAll);
					delayTimer.start();
					
					sbdvSel.enabled = false;
				}
			}
/**
 *  when an item is selected
 */			
private function handleAutoCompleteChange():void
{
	// does nothing !
	
}				

private function showComboAll( event:TimerEvent ):void
			{
				sbdvSel.enabled = true;
				sbdvSel.search();
}

public var mpGraphicList:ArrayCollection = new ArrayCollection();
/**
 * Draw MP symbol
 */
private function drawMilepost(mp:Object):void {
	try 
	{
 
		CursorManager.setBusyCursor ();
		var pnt:MapPoint = new MapPoint(); 
	
		pnt.x = mp.lon as Number;
		pnt.y = mp.lat as Number;
	
		var g:Graphic = new Graphic();
		g.geometry = pnt;
		g.symbol = mpSymb;
		g.attributes = { "sbdv":mp.sbdvName as String, "mile":mp.mile};
		
		mpGraphicList.addItem(g);
		Model.getInstance ().graphicsLayer.add(g);
		/**
		 *  Type Error 1009 shall be throwed at runtime, if single point is used 
		 *  to set the map extent !!!!
		 */
		
		if (mpGraphicList.length > 1){
			var ext:Extent = GraphicUtil.getGraphicsExtent(mpGraphicList.toArray());
			Model.getInstance().map.extent = ext.expand(1.5);
		} else {
				Model.getInstance().map.centerAt(pnt);
				Model.getInstance().map.scale = 18036;
		}
		 
		CursorManager.removeBusyCursor ();
		
		
	} catch (err : Error)
	{
		var errorEvent : AppEvent = new AppEvent (AppEvent.APP_ERROR);
		errorEvent.data = "Error when drawing MP location: "+err.toString();
		errorEvent.dispatch ();
	}
}

/**
 *  clean all MPs
 */
private function cleanAll():void {
	
		for (var i:int = 0; i < mpGraphicList.length; i++ ) {
			Model.getInstance ().graphicsLayer.remove( mpGraphicList[i] as Graphic);	
		}
		mpGraphicList.removeAll();
		mpArray.removeAll();
}

/**
 *  del select Item
 */
private function delSelected():void {
		mpArray.removeItemAt(mpArray.getItemIndex(mpList.selectedItem));
		// clean all graphics first
		for (var i:int = 0; i < mpGraphicList.length; i++ ) {
			Model.getInstance ().graphicsLayer.remove( mpGraphicList[i] as Graphic);	
		}
		mpGraphicList.removeAll();
		// redraw
		for (var k:int = 0; k < mpArray.length; k++ ) {
				drawMilepost(mpArray.getItemAt(k));
		}
}

private function saveToFile():void {
	var jsonString:String;
	//jsonString= JSON.encode(mpArray.toArray());
	var rnd : Number = Math.round(Math.random()*1000);
	/*
	var httpRequest:HTTPService =new HTTPService();
		httpRequest.url="SaveMilepost?x="+rnd;
	var parameters:Object = new Object();
	parameters.data=jsonString;
	httpRequest.request=parameters;
	httpRequest.resultFormat="text";
	httpRequest.addEventListener(ResultEvent.RESULT, subListResulteHandler);
	httpRequest.addEventListener("fault", serviceFaultHandler);
	httpRequest.send();
	*/
	
	for (var i:int = 0; i < mpArray.length; i++ ) {
		if (i == 0)
			jsonString = "{\"mpArray\":["+JSON.encode(mpArray.getItemAt(i));
		else	
			jsonString=jsonString+","+JSON.encode(mpArray.getItemAt(i));
	}
	
			jsonString = jsonString + "]}";
	
	var u:URLRequest = new URLRequest("SaveMilepost?data="+jsonString+"&x="+rnd);
	//navigateToURL(u, "_blank");
	navigateToURL(u, "_self");	
}

// double click handler
protected function mpDoubleClickHandler(event:ListEvent):void {
	var lat:Number = event.currentTarget.selectedItem.lat;
	var lon:Number = event.currentTarget.selectedItem.lon;
	
	var dcEvent : AppEvent = new AppEvent (AppEvent.MP_DOUBLECLICK);
	dcEvent.data = { "x":lon, "y":lat };
	dcEvent.dispatch ();
}

private function mpGridInit(event:FlexEvent):void {
	//Alert.show("enable grid double click");
	event.currentTarget.itemRenderer.properties = {doubleClickEnabled:true};
}

	/**
	 *  When a stn is clicked
	 * @param	e
	 */
	private function mapToMilepost(e : AppEvent):void {
		//Alert.show("click is captured");
		Model.getInstance().map.scale = 18036;
		var pnt:MapPoint = new MapPoint(e.data.x, e.data.y);
		Model.getInstance().map.centerAt(pnt);
	}